package com.weishenai.customerassistant.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weishenai.customerassistant.common.dto.MeterFactFinderStatisticsDto;
import com.weishenai.customerassistant.common.dto.MeterFactFinderWeekStatisticsDto;
import com.weishenai.customerassistant.common.dto.MeterResultStatisticsDto;
import com.weishenai.customerassistant.common.dto.MeterTypeStatisticsDto;
import com.weishenai.customerassistant.common.enu.DateTimeTypeEnum;
import com.weishenai.customerassistant.entity.MetersResult;
import com.weishenai.customerassistant.mapper.FactFinderMapper;
import com.weishenai.customerassistant.mapper.MetersResultMapper;
import com.weishenai.customerassistant.service.FactFinderService;
import com.weishenai.customerassistant.service.MetersResultsService;
import com.weishenai.customerassistant.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class MetersResultServiceImpl extends ServiceImpl<MetersResultMapper, MetersResult> implements MetersResultsService {
    @Autowired
    private MetersResultMapper metersResultMapper;

    @Autowired
    private FactFinderMapper factFinderMapper;

    @Autowired
    private FactFinderService factFinderService;
//    @Override
//    public MetersResult findMetersResultById(Long id) {
//        QueryWrapper<MetersResult> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("id", id);
//        return metersResultMapper.selectOne(queryWrapper);
//    }

    /**
     * 根据id删除结果
     *
     * @param id
     * @return
     */
    @Override
    public Integer delMetersResultById(Long id) {
        QueryWrapper<MetersResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        return metersResultMapper.delete(queryWrapper);
    }

    /**
     * 插入一条结果数据
     */
    @Override
    public Integer insertOneMetersResult(MetersResult metersResult) {
//        metersResult.setFactFinder(((User) SecurityUtils.getSubject().getPrincipal()).getUsername());
        metersResult.setCreatedTime(DateUtils.getTime());
        return metersResultMapper.insert(metersResult);
    }

    /**
     * 分页查询所有的结果数据
     *
     * @param pageNumber
     * @param pageSize
     * @param keyWord
     */
    @Override
    public IPage<MetersResult> selectAll(String substation, Integer pageNumber, Integer pageSize, String keyWord) {
        QueryWrapper<MetersResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("substation_name", substation);
        if (StringUtils.isNotEmpty(keyWord)) {
            queryWrapper.like("fact_finder", keyWord);
        }
        queryWrapper.orderByDesc("created_time");
        IPage<MetersResult> page = new Page<>(pageNumber, pageSize);
        return metersResultMapper.selectPage(page, queryWrapper);
    }

    @Override
    public IPage<MetersResult> selectByDate(String substation, String startDate, String endDate, Integer pageNum, Integer pageSize) {
        QueryWrapper<MetersResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("substation_name", substation);
        queryWrapper.ge("created_time", startDate);
        queryWrapper.lt("created_time", endDate);
        queryWrapper.orderByDesc("created_time");
        IPage<MetersResult> page = new Page<>(pageNum, pageSize);
        return metersResultMapper.selectPage(page, queryWrapper);
    }

    @Override
    public MetersResult selectById(Long id) {
        QueryWrapper<MetersResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        return metersResultMapper.selectOne(queryWrapper);
    }

    @Override
    public IPage<MetersResult> selectByState(String factFinderName, String state, Integer pageNum, Integer pageSize) {
        QueryWrapper<MetersResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fact_finder", factFinderName);
        queryWrapper.eq("state", state);
        queryWrapper.orderByDesc("created_time");
        IPage<MetersResult> page = new Page<>(pageNum, pageSize);
        return metersResultMapper.selectPage(page, queryWrapper);
    }

    @Override
    public List<MeterResultStatisticsDto> listMeterResultStatistics() {
        return factFinderMapper.listFactResultStatistics();
    }

    @Override
    public List<MeterTypeStatisticsDto> listMeterTypeStatisticsBySubstation(String substation, int type) {
        Map<Object, Object> time = getTimeByType(type);
        return metersResultMapper.listMeterTypeStatisticsBySubstation(substation, time.get("startTime").toString(), time.get("endTime").toString());
    }

    @Override
    public List<MeterFactFinderStatisticsDto> listMeterFactFinderStatisticsBySubstation(String substation, int type) {
        Map<Object, Object> time = getTimeByType(type);
        return metersResultMapper.listFactFinderStatisticsBySubstation(substation, time.get("startTime").toString(), time.get("endTime").toString());
    }


    @Override
    public Map<Object, Object> getBaseStatisticsInfo(String substation) {
        return MapUtil.builder()
                .put("total",
                        metersResultMapper.selectCount(
                                Wrappers.lambdaQuery(MetersResult.class)
                                        .eq(MetersResult::getSubstationName, substation)))
                .put("yesterdayAdd",
                        metersResultMapper.selectCount(
                                Wrappers.lambdaQuery(MetersResult.class)
                                        .eq(MetersResult::getSubstationName, substation)
                                        .ge(MetersResult::getCreatedTime,DateUtil.beginOfDay(DateUtil.yesterday()).toString())
                                        .le(MetersResult::getCreatedTime,DateUtil.beginOfDay(DateUtil.date()).toString())))
                .put("workerTotal",factFinderService.getCountBySubstation(substation))
                .map();
    }

    @Override
    public Map<Object, Object> getFactFinderWeekJob(String substation, String fact) {

        return MapUtil.builder()
                .put("factName", fact)
                .put("statistics", metersResultMapper.getFactFinderWeekJob(substation, fact)).map();
    }

    /**
     * 通过type获取起始与结束时间
     * yesterday：昨天0点开始点到现在结束
     * lastWeek： 上周0点开始到今天结束
     * lastMonth： 上个月0点开始 到今天结束
     * 如果不存在则起始时间为一年前
     *
     * @param type
     * @return
     */
    private Map<Object, Object> getTimeByType(int type) {
        String startTime;
        String endTime = DateUtil.endOfDay(DateUtil.date()).toString();
        if (DateTimeTypeEnum.ONE_DAY.getCode() == type) {
            startTime = DateUtil.beginOfDay(DateUtil.yesterday()).toString();
        } else if (DateTimeTypeEnum.ONE_WEEK.getCode() == type) {
            startTime = DateUtil.beginOfDay(DateUtil.lastWeek()).toString();
        } else if (DateTimeTypeEnum.ONE_MONTH.getCode() == type) {
            startTime = DateUtil.beginOfDay(DateUtil.lastMonth()).toString();
        } else {
            startTime = String.valueOf(DateUtil.beginOfDay(DateUtil.offset(DateUtil.date(), DateField.YEAR, -1)));
        }
        return MapUtil.builder()
                .put("startTime", startTime)
                .put("endTime", endTime).map();
    }
}
